package br.edu.ufcg.msnlab2.grupo07;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;
import mathExpr.parser.javacc.ParseException;
import br.edu.ufcg.msnlab2.MSNLabException;
import br.edu.ufcg.msnlab2.grupo07.monteCarlo.MonteCarloSolver;
import br.edu.ufcg.msnlab2.grupo07.monteCarlo.PlainMonteCarloSolverImpl;
import br.edu.ufcg.msnlab2.grupo07.monteCarlo.Tuple;
import br.edu.ufcg.msnlab2.misc.Function;
import br.edu.ufcg.msnlab2.misc.FunctionImpl;


/**
 * This class contains tests for the abstract class of the
 * Monte Carlo solver.
 * @author David Candeia
 * @author Felipe Leal
 */
public class MonteCarloSolverTest extends TestCase{
	
	private MonteCarloSolver solver;
	
	public void setUp(){
		solver = new PlainMonteCarloSolverImpl();
	}
	
	/**
	 * This method contains tests for the process of sampling points for functions that contains
	 * only one variable.
	 * @throws MSNLabException Exception thrown if any invalid condition is reached while sampling the
	 * points
	 */
	public void testSamplePointsWithOneVariable() throws MSNLabException{
		
		//Creating variable limits
		Map<String, Tuple<Double, Double>> limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(1.0d, 10.0d));
		
		Map<String, List<Double>> sampledPoints = solver.samplePoints(limits, 5);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 1);
		assertEquals(sampledPoints.get("x").size(), 5);
		
		List<Double> values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= 1.0d);
			assertTrue(value <= 10.0d);
		}
		
		//Testing small values in limits
		limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(0.0d, 0.00098d));
		
		sampledPoints = solver.samplePoints(limits, 5);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 1);
		assertEquals(sampledPoints.get("x").size(), 5);
		
		values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= 0.0d);
			assertTrue(value <= 0.00098d);
		}
		
		//Testing big values in limits
		limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(1000000000d, 100000000000d));
		
		sampledPoints = solver.samplePoints(limits, 5);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 1);
		assertEquals(sampledPoints.get("x").size(), 5);
		
		values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= 1000000000d);
			assertTrue(value <= 100000000000d);
		}
		
		//Testing negative values
		limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(-1000000000d, -1d));
		
		sampledPoints = solver.samplePoints(limits, 5);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 1);
		assertEquals(sampledPoints.get("x").size(), 5);
		
		values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= -1000000000d);
			assertTrue(value <= -1d);
		}
		
		//Invalid arguments
		sampledPoints = solver.samplePoints(new HashMap<String, Tuple<Double,Double>>(), 5);
		assertNotNull(sampledPoints);
		
		try{
			sampledPoints = solver.samplePoints(new HashMap<String, Tuple<Double,Double>>(), -10);
			fail("Invalid number of points!");
		}catch(MSNLabException e){
		}
		
		try{
			sampledPoints = solver.samplePoints(new HashMap<String, Tuple<Double,Double>>(), 0);
			fail("Invalid number of points!");
		}catch(MSNLabException e){
		}
		
		try{
			sampledPoints = solver.samplePoints(null, 10);
			fail("Invalid list of limits!");
		}catch(RuntimeException e){
		}
	}
	
	/**
	 * This method contains tests for the process of sampling points for functions that contains
	 * two or more variables.
	 * @throws MSNLabException Exception thrown if any invalid condition is reached while sampling the
	 * points
	 */
	public void testSamplePointsWithTwoOrMoreVariables() throws MSNLabException{
		//Creating limits for three variables
		Map<String, Tuple<Double, Double>> limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(1.0d, 10.0d));
		limits.put("y", new Tuple<Double, Double>(0.0d, 1.5d));
		limits.put("z", new Tuple<Double, Double>(30.0d, 45.57655d));
		
		Map<String, List<Double>> sampledPoints = solver.samplePoints(limits, 20);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 3);
		assertEquals(sampledPoints.get("x").size(), 20);
		assertEquals(sampledPoints.get("y").size(), 20);
		assertEquals(sampledPoints.get("z").size(), 20);
		
		List<Double> values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= 1.0d);
			assertTrue(value <= 10.0d);
		}
		
		values = sampledPoints.get("y");
		for(Double value : values){
			assertTrue(value >= 0.0d);
			assertTrue(value <= 1.5d);
		}
		
		values = sampledPoints.get("z");
		for(Double value : values){
			assertTrue(value >= 30.0d);
			assertTrue(value <= 45.57655d);
		}
		
		//Using a mix of big and small limits
		limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(-0.009d, 0.000000875d));
		limits.put("y", new Tuple<Double, Double>(9999990.0d, 999999999999d));
		limits.put("z", new Tuple<Double, Double>(30.0d, 45.57655d));
		
		sampledPoints = solver.samplePoints(limits, 20);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 3);
		assertEquals(sampledPoints.get("x").size(), 20);
		assertEquals(sampledPoints.get("y").size(), 20);
		assertEquals(sampledPoints.get("z").size(), 20);
		
		values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= -0.009d);
			assertTrue(value <= 0.000000875d);
		}
		
		values = sampledPoints.get("y");
		for(Double value : values){
			assertTrue(value >= 9999990.0d);
			assertTrue(value <= 999999999999d);
		}
		
		values = sampledPoints.get("z");
		for(Double value : values){
			assertTrue(value >= 30.0d);
			assertTrue(value <= 45.57655d);
		}
		
		//Using only negative values
		limits = new HashMap<String, Tuple<Double,Double>>();
		limits.put("x", new Tuple<Double, Double>(-0.009d, -0.000000875d));
		limits.put("y", new Tuple<Double, Double>(-9999990.0d, -9999d));
		limits.put("z", new Tuple<Double, Double>(-90.0d, -45.57655d));
		
		sampledPoints = solver.samplePoints(limits, 20);
		assertNotNull(sampledPoints);
		assertEquals(sampledPoints.size(), 3);
		assertEquals(sampledPoints.get("x").size(), 20);
		assertEquals(sampledPoints.get("y").size(), 20);
		assertEquals(sampledPoints.get("z").size(), 20);
		
		values = sampledPoints.get("x");
		for(Double value : values){
			assertTrue(value >= -0.009d);
			assertTrue(value <= -0.000000875d);
		}
		
		values = sampledPoints.get("y");
		for(Double value : values){
			assertTrue(value >= -9999990.0d);
			assertTrue(value <= -9999d);
		}
		
		values = sampledPoints.get("z");
		for(Double value : values){
			assertTrue(value >= -90.0d);
			assertTrue(value <= -45.57655d);
		}
	}
	
	/**
	 * This method contains tests for the method that given a set of sampled points evaluates
	 * the function at each sampled point and sums all function values. Here it's considered
	 * only functions with one variable.
	 * @throws ParseException Exception thrown if an invalid function expression is being parsed
	 * @throws MSNLabException Exception thrown if any invalid condition is reached while calculating the
	 * sum of the function values in each sampled point
	 */
	public void testCalculateFunctionValueInEachPointWithOneVariable() throws ParseException, MSNLabException{
		
		//Configuring expression
		Function config = new FunctionImpl("x^2+10");
		
		//Collection of points
		Map<String, List<Double>> sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		
		double calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
		assertEquals(calculateFunctionValueInEachPoint, 9.9999999999999805e+029);
		
		//Testing with another variable name
		config = new FunctionImpl("sin(a)");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(10.0d);
		sampledPoints.get("a").add(0.000000011d);
		sampledPoints.get("a").add(999999999999999.0d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
	
		assertEquals(calculateFunctionValueInEachPoint, 0.35154388206835241, 0.00001);
		
		//Testing another function
		config = new FunctionImpl("1/(jac+100)");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("jac", new ArrayList<Double>());
		sampledPoints.get("jac").add(10.0d);
		sampledPoints.get("jac").add(0.000000011d);
		sampledPoints.get("jac").add(999999999999999.0d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
		assertEquals(calculateFunctionValueInEachPoint, 0.01909090908981009, 0.00001);
		
		//Trying to substitute an invalid variable
		config = new FunctionImpl("1/(jac+100)");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("\"jac\""));
		}
		
		//Using an empty set of sampled points
		config = new FunctionImpl("1/(x+100) + 10*x");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 0);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("set of sampled points"));
		}
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(new HashMap<String, List<Double>>(), config, 0);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("set of sampled points"));
		}
		
		//Invalid number of points
		config = new FunctionImpl("1/(jac+100)");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("jac", new ArrayList<Double>());
		sampledPoints.get("jac").add(10.0d);
		sampledPoints.get("jac").add(0.000000011d);
		sampledPoints.get("jac").add(999999999999999.0d);
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 0);
			fail("Invalid number of points!");
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("number of points"));
		}
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, -10);
			fail("Invalid number of points!");
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("number of points"));
		}
		
		//Invalid function definition
		config = new FunctionImpl("x^3+10*x");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.put("t", new ArrayList<Double>());
		sampledPoints.get("t").add(1.0d);
		sampledPoints.get("t").add(0.00000099d);
		
		try{
			solver.calculateFunctionValueInEachPoint(sampledPoints, null, 2);
			fail("Invalid function!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid function!"));
		}
		
		//Sampling points fore more variables than existed in the function
		config = new FunctionImpl("x^3+10*x");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.put("t", new ArrayList<Double>());
		sampledPoints.get("t").add(1.0d);
		sampledPoints.get("t").add(0.00000099d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 2);
		assertEquals(calculateFunctionValueInEachPoint, 1100.00000011d);
		
		//Putting more points than what is determined as a parameter
		config = new FunctionImpl("x^3+10*x");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999d);
		sampledPoints.get("x").add(20d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 2);
		assertEquals(calculateFunctionValueInEachPoint, 1100.00000011d);
	}
	
	/**
	 * This method contains tests for the method that given a set of sampled points evaluates
	 * the function at each sampled point and sums all function values. Here it's considered
	 * only functions with two or more variables.
	 * @throws ParseException Exception thrown if an invalid function expression is being parsed
	 * @throws MSNLabException Exception thrown if any invalid condition is reached while calculating the
	 * sum of the function values in each sampled point
	 */
	public void testCalculateFunctionValueInEachPointWithMoreThanOneVariable() throws ParseException, MSNLabException{
		//Configuring expression
		Function config = new FunctionImpl("x^2+10*a");
		
		//Collection of points
		Map<String, List<Double>> sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(9999999999999d);
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(1.0d);
		sampledPoints.get("a").add(2d);
		
		double calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 2);
		assertEquals(calculateFunctionValueInEachPoint, 9.9999999999980007e+025);
		
		//Testing with another variable name
		config = new FunctionImpl("sin(a)+b");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(10.0d);
		sampledPoints.get("a").add(0.000000011d);
		sampledPoints.put("b", new ArrayList<Double>());
		sampledPoints.get("b").add(9999999d);
		sampledPoints.get("b").add(-0.987765544433d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 2);
		assertEquals(calculateFunctionValueInEachPoint, 9999997.4682133552, 0.00001);
		
		//Putting more points that the amount determined as a parameter
		config = new FunctionImpl("sin(a)+b");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(10.0d);
		sampledPoints.get("a").add(0.000000011d);
		sampledPoints.get("a").add(100000d);
		sampledPoints.put("b", new ArrayList<Double>());
		sampledPoints.get("b").add(9999999d);
		sampledPoints.get("b").add(-0.987765544433d);
		sampledPoints.get("b").add(-0.987765544433d);
		
		calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 2);
		assertEquals(calculateFunctionValueInEachPoint, 9999997.4682133552, 0.00001);
		
		//Sampling points for only one of the variables
		config = new FunctionImpl("1/(x+100) + 10*t");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("\"t\""));
		}
		
		//Empty set of points
		config = new FunctionImpl("1/(x+100) + 10*t");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.put("t", new ArrayList<Double>());
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(sampledPoints, config, 3);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			System.out.println(e.getMessage());
			assertTrue(e.getMessage().contains("Invalid set of sampled points"));
		}
		
		try{
			calculateFunctionValueInEachPoint = solver.calculateFunctionValueInEachPoint(new HashMap<String, List<Double>>(), config, 3);
			fail("Variable and sampled points do not match!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid set of sampled points"));
		}
		
		//Invalid function
		config = new FunctionImpl("sin(a)+b");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(10.0d);
		sampledPoints.get("a").add(0.000000011d);
		sampledPoints.get("a").add(100000d);
		sampledPoints.put("b", new ArrayList<Double>());
		sampledPoints.get("b").add(9999999d);
		sampledPoints.get("b").add(-0.987765544433d);
		sampledPoints.get("b").add(-0.987765544433d);
		
		try{
			solver.calculateFunctionValueInEachPoint(sampledPoints, null, 2);
			fail("Invalid function!");
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid function"));
		}
		
		//Invalid number of points
		config = new FunctionImpl("sin(a)+b");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("a", new ArrayList<Double>());
		sampledPoints.get("a").add(10.0d);
		sampledPoints.get("a").add(0.000000011d);
		sampledPoints.get("a").add(100000d);
		sampledPoints.put("b", new ArrayList<Double>());
		sampledPoints.get("b").add(9999999d);
		sampledPoints.get("b").add(-0.987765544433d);
		sampledPoints.get("b").add(-0.987765544433d);
		
		try{
			solver.calculateFunctionValueInEachPoint(sampledPoints, config, 0);
			fail("Invalid function!");
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Invalid number of points"));
		}
		
		try{
			solver.calculateFunctionValueInEachPoint(sampledPoints, config, -20);
			fail("Invalid function!");
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Invalid number of points"));
		}
	}

	/**
	 * This method contains tests for the calculation of variance, given a set of sampled points,
	 * for functions that contains only one variable.
	 * @throws ParseException Exception thrown if an invalid function expression is being parsed
	 * @throws MSNLabException Exception thrown if any invalid condition is reached while calculating the
	 * variance for the function
	 */
	public void testCalculateVarianceForAFunctionWithOneVariable() throws ParseException, MSNLabException{
		
		//A very simple function with no variance
		Function config = new FunctionImpl("x");
		
		//Collection of points
		Map<String, List<Double>> sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(10.0d);
		double variance = solver.calculateVariance(config, sampledPoints, 10d, 10, 3);
		assertEquals(variance, 0d);
		
		//A function with high variance
		config = new FunctionImpl("x^2");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		variance = solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, 10, 3);
		assertEquals(variance, 7.407407407407378E60d);
		
		//An empty set of sampled points
		config = new FunctionImpl("x^2");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		
		try{
			solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, 10, 3);
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid set of sampled points"));
		}
		
		try{
			solver.calculateVariance(config, new HashMap<String, List<Double>>(), 3.3333333333333268e+029, 10, 3);
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid set of sampled points"));
		}
		
		//An invalid function
		config = new FunctionImpl("x^2");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		try{
			solver.calculateVariance(null, sampledPoints, 3.3333333333333268e+029, 10, 3);
		}catch(RuntimeException e){
			assertTrue(e.getMessage().contains("Invalid function"));
		}
		
		//Invalid number of points
		config = new FunctionImpl("x^2");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		try{
			solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, 10, 0);
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Invalid number of points"));
		}
		
		try{
			solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, 10, -1000);
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Invalid number of points"));
		}
		
		//Invalid volume
		config = new FunctionImpl("x^2");
		
		//Collection of points
		sampledPoints = new HashMap<String, List<Double>>();
		sampledPoints.put("x", new ArrayList<Double>());
		sampledPoints.get("x").add(10.0d);
		sampledPoints.get("x").add(0.000000011d);
		sampledPoints.get("x").add(999999999999999.0d);
		try{
			solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, -100, 3);
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Negative interval is not allowed"));
		}
		
		try{
			solver.calculateVariance(config, sampledPoints, 3.3333333333333268e+029, 0, 3);
		}catch(MSNLabException e){
			assertTrue(e.getMessage().contains("Integral is not determined for a point"));
		}
	}

	
}
